/*
 * @lc app=leetcode.cn id=468 lang=cpp
 *
 * [468] 验证IP地址
 */

// @lc code=start
#include <bits/stdc++.h>
using namespace std;

class Solution {
    const string NEITHER = "Neither";
    const string V4 = "IPv4";
    const string V6 = "IPv6";

    vector<string> split(const string& s, string&& str)
    {
        vector<string> ans;
        int i = 0;
        while(true)
        {
            auto end = s.find(str, i);
            auto tmp = s.substr(i, end - i);
            ans.push_back(tmp);
            i = end + str.size();
            if(end == s.npos) break;
        }
        return ans;
    }
    bool validNumberBase10(const string& num)
    {
        if(num.size() > 1 && num[0] == '0') return false;
        if(num.size() > 3) return false;
        if(num.size() == 0) return false;
        int ans = 0;
        for(int i = 0; i < num.size(); i++)
        {
            if(num[i] < '0' || num[i] > '9') return false;
            ans *= 10;
            ans += num[i] - '0';
        }
        return ans < 256;
    }
    bool validNumberBase16(const string& num)
    {
        if(num.size() > 4 || num.size() == 0) return false;
        for(int i = 0; i < num.size(); i++)
        {
            if(!( 
                (num[i]>='0' && num[i] <= '9') || 
                (num[i] >= 'a' && num[i] <= 'f') || 
                (num[i] >= 'A' && num[i] <= 'F'))
            )
            {
                return false;
            }
        }
        return true;
    }
    string validIPV4(string& queryip)
    {
        auto v = split(queryip, ".");
        if(v.size() != 4)
        {
            return NEITHER;
        }
        for(auto& s : v)
        {
            if(!validNumberBase10(s)) return NEITHER;
        }
        return V4;
    }
    string validIPV6(string& queryip)
    {
        auto v = split(queryip, ":");
        if(v.size() != 8)
        {
            return NEITHER;
        }
        for(auto& s : v)
        {
            if(!validNumberBase16(s))
            {
                return NEITHER;
            }
        }
        return V6;
    }
public:
    string validIPAddress(string queryIP) {
        if(queryIP.find('.') != queryIP.npos)
        {
            return validIPV4(queryIP);
        }
        else if(queryIP.find(':') != queryIP.npos)
        {
            return validIPV6(queryIP);
        }
        return NEITHER;
    }
};
// int main(int argc, char const *argv[])
// {
//     cout << Solution().validIPAddress("2001:db8:85a3:0::8a2E:0370:7334") << endl;
//     return 0;
// }

// @lc code=end

